package com.chuangjiangx.member.basic.ddd.query;

import com.chuangjiangx.commons.CJBeanUtils;
import com.chuangjiangx.commons.DateUtils;
import com.chuangjiangx.commons.page.PagingResult;

import com.chuangjiangx.domain.shared.model.Sex;
import com.chuangjiangx.member.basic.ddd.dal.mapper.MemberCountDalMapper;
import com.chuangjiangx.member.basic.ddd.dal.dto.DateTimeMemberVolume;
import com.chuangjiangx.member.basic.ddd.dal.dto.MemberVolumeDetail;
import com.chuangjiangx.member.basic.ddd.dal.dto.StoreMemberVolume;
import com.chuangjiangx.member.basic.ddd.dal.dto.TerminalMemberVolume;
import com.chuangjiangx.member.basic.ddd.query.condition.MemberVolumeCondition;
import com.chuangjiangx.member.basic.ddd.query.condition.MemberVolumeDetailCondition;
import com.chuangjiangx.member.basic.ddd.domain.model.MbrSourceTerminal;
import com.chuangjiangx.member.basic.ddd.query.dto.*;
import com.chuangjiangx.member.stored.ddd.query.dto.StoreMemberVolumeAndTotalDTO;
import com.chuangjiangx.member.stored.ddd.query.dto.StoreMemberVolumeDTO;
import com.github.pagehelper.PageInfo;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 会员量统计
 */
@Component
public class MemberCountQuery {


    private Logger logger = LoggerFactory.getLogger(MemberCountQuery.class);

    private final MemberCountDalMapper memberCountDalMapper;

    @Autowired
    public MemberCountQuery(MemberCountDalMapper memberCountDalMapper) {
        this.memberCountDalMapper = memberCountDalMapper;
    }


    /**
     * 统计每天会员量/每个小时会员量--商户权限
     */
    public MemberVolumeAndTotalDTO getDayOrHourCountListForMerchant(MemberVolumeCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        condition.setRegisterStoreId(null);
        List<DateTimeMemberVolume> list = dayOrHourCountList(condition);
        logger.info("统计每天会员量/每个小时会员量--商户权限:" + list);
        return dayOrHourCountListConvert(condition, list);
    }

    /**
     * 统计每天会员量/每个小时会员量--门店权限
     */
    public MemberVolumeAndTotalDTO getDayOrHourCountListForForStore(MemberVolumeCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        Assert.notNull(condition.getRegisterStoreId(), "门店id不能为空");
        List<DateTimeMemberVolume> list = dayOrHourCountList(condition);
        logger.info("统计每天会员量/每个小时会员量--门店权限:" + list);
        return dayOrHourCountListConvert(condition, list);
    }

    private List<DateTimeMemberVolume> dayOrHourCountList(MemberVolumeCondition condition) {
        RowBounds rowBounds = new RowBounds(condition.offset(), condition.limit());
        List<DateTimeMemberVolume> list;
        Long time = condition.getEndTime().getTime() - condition.getStartTime().getTime();
        if (time <= 24 * 60 * 60 * 1000) {
            //每个小时会员量
            list = memberCountDalMapper.getHourCountListWithRowBounds(condition, rowBounds);
            logger.info("统计每小时会员量" + list);
        } else {
            //每天会员量
            condition.setEndTime(DateUtils.addDate(condition.getEndTime()));
            list = memberCountDalMapper.getDayCountListWithRowBounds(condition, rowBounds);
            logger.info("统计每天会员量" + list);
        }
        return list;
    }


    private MemberVolumeAndTotalDTO dayOrHourCountListConvert(MemberVolumeCondition condition, List<DateTimeMemberVolume> list) {
        List<DateTimeMemberVolumeDTO> dateTimeMemberVolumeDTOList = new ArrayList<>();
        //转换
        int totalCount = memberCountDalMapper.getTotalCount(condition.getMerchantId());
        //xml中sql按时间统计 需要加一天
        condition.setEndTime(DateUtils.addDate(condition.getEndTime()));
        int timeCount = memberCountDalMapper.getTimeCount(condition);
        TotalDTO totalDTO = new TotalDTO();
        totalDTO.setTimeCount(timeCount);
        totalDTO.setTotalCount(totalCount);

        list.forEach(dateTimeMemberVolume -> {
            DateTimeMemberVolumeDTO dateTimeMemberVolumeDTO = new DateTimeMemberVolumeDTO();
            BeanUtils.copyProperties(dateTimeMemberVolume, dateTimeMemberVolumeDTO);
            dateTimeMemberVolumeDTOList.add(dateTimeMemberVolumeDTO);
        });

        MemberVolumeAndTotalDTO memberVolumeAndTotalDTO = new MemberVolumeAndTotalDTO();
        memberVolumeAndTotalDTO.setDatas(dateTimeMemberVolumeDTOList);
        memberVolumeAndTotalDTO.setTotal(totalDTO);
        return memberVolumeAndTotalDTO;
    }


    /**
     * 按门店统计列表
     */
    public PagingResult<StoreMemberVolumeDTO> getStoreCountList(MemberVolumeCondition condition) {
        RowBounds rowBounds = new RowBounds(condition.offset(), condition.limit());
        condition.setEndTime(DateUtils.addDate(condition.getEndTime()));
        List<StoreMemberVolume> list = memberCountDalMapper.getStoreCountListWithRowBounds(condition, rowBounds);
        logger.info("按门店统计列表:" + list);

        PageInfo<StoreMemberVolume> pageInfo = new PageInfo<>(list);
        List<StoreMemberVolumeDTO> storeMemberVolumeDTOList = list.stream().map(storeMemberVolume -> {
            StoreMemberVolumeDTO storeMemberVolumeDTO = storeSetCountConvert(storeMemberVolume);
            return storeMemberVolumeDTO;
        }).collect(Collectors.toList());
        return new PagingResult<>(pageInfo.getPageSize(), pageInfo.getPageNum(),
                pageInfo.getTotal(), storeMemberVolumeDTOList);
    }


    /**
     * 按门店统计前10个(图表)
     */
    public StoreMemberVolumeAndTotalDTO getStoreCountTop10Chart(MemberVolumeCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        condition.setEndTime(DateUtils.addDate(condition.getEndTime()));
        List<StoreMemberVolume> list = memberCountDalMapper.getTop10StoreCountList(condition);
        List<StoreMemberVolumeDTO> dtoList = list.stream().map(storeMemberVolume -> {
            StoreMemberVolumeDTO storeMemberVolumeDTO = storeSetCountConvert(storeMemberVolume);
            return storeMemberVolumeDTO;
        }).collect(Collectors.toList());
        return storeCountConvert(condition, dtoList);
    }

    private StoreMemberVolumeDTO storeSetCountConvert(StoreMemberVolume storeMemberVolume) {
        StoreMemberVolumeDTO storeMemberVolumeDTO = new StoreMemberVolumeDTO();
        BeanUtils.copyProperties(storeMemberVolume, storeMemberVolumeDTO);
        if (storeMemberVolume.getStoreName() == null) {
            storeMemberVolumeDTO.setStoreName(storeMemberVolume.getName());
        }
        return storeMemberVolumeDTO;
    }

    private StoreMemberVolumeAndTotalDTO storeCountConvert(MemberVolumeCondition condition,
                                                           List<StoreMemberVolumeDTO> list) {
        int totalCount = memberCountDalMapper.getTotalCount(condition.getMerchantId());//总数量
        int timeCount = memberCountDalMapper.getTimeCount(condition);////某段时间总数量
        TotalDTO totalDTO = new TotalDTO();
        totalDTO.setTotalCount(totalCount);
        totalDTO.setTimeCount(timeCount);

        StoreMemberVolumeAndTotalDTO storeMemberVolumeAndTotalDTO = new StoreMemberVolumeAndTotalDTO();
        storeMemberVolumeAndTotalDTO.setDatas(list);
        storeMemberVolumeAndTotalDTO.setTotal(totalDTO);
        return storeMemberVolumeAndTotalDTO;
    }


    /**
     * 按照终端类型统计某个时间段会员量图表--商户权限
     */
    public TerminalMemberVolumeAndTotalDTO getTerminalCountChartForMerchant(MemberVolumeCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        condition.setRegisterStoreId(null);
        condition.setEndTime(DateUtils.addDate(condition.getEndTime()));
        RowBounds rowBounds = new RowBounds(condition.offset(), condition.limit());
        List<TerminalMemberVolume> list = memberCountDalMapper.getTerminalCountListWithRowBounds(condition, rowBounds);
        logger.debug("按照终端类型统计某个时间段会员量--商户权限:" + list);
        return terminalCountListConvert(condition, list);

    }

    /**
     * 按照终端类型统计某个时间段会员量图表--门户权限
     */
    public TerminalMemberVolumeAndTotalDTO getTerminalCountChartForStore(MemberVolumeCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        Assert.notNull(condition.getRegisterStoreId(), "门店id不能为空");
        condition.setEndTime(DateUtils.addDate(condition.getEndTime()));
        RowBounds rowBounds = new RowBounds(condition.offset(), condition.limit());
        List<TerminalMemberVolume> list = memberCountDalMapper.getTerminalCountListWithRowBounds(condition, rowBounds);
        logger.debug("按照终端类型统计某个时间段会员量--门户权限:" + list);
        return terminalCountListConvert(condition, list);
    }

    /**
     * 按照终端类型统计某个时间段会员量列表--商户权限
     */
    public PagingResult<TerminalMemberVolumeDTO> getTerminalCountListForMerchant(MemberVolumeCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        condition.setRegisterStoreId(null);
        condition.setEndTime(DateUtils.addDate(condition.getEndTime()));
        RowBounds rowBounds = new RowBounds(condition.offset(), condition.limit());
        List<TerminalMemberVolume> list = memberCountDalMapper.getTerminalCountListWithRowBounds(condition, rowBounds);
        logger.info("按照终端类型统计某个时间段会员量--商户权限:" + list);
        PageInfo<TerminalMemberVolume> pageInfo = new PageInfo<>(list);

        List<TerminalMemberVolumeDTO> terminalMemberVolumeDTOList = CJBeanUtils.convertCollection(
                list, TerminalMemberVolumeDTO.class, (source, target) -> {
                    target.setTerminalTypeText(source.getRegisterTerminalType() == null ? "-" : MbrSourceTerminal.getSourceTerminal(source.getRegisterTerminalType()).name);//杨括修改
                });
        return new PagingResult<>(pageInfo.getPageSize(), pageInfo.getPageNum(),
                pageInfo.getTotal(), terminalMemberVolumeDTOList);
    }

    /**
     * 按照终端类型统计某个时间段会员量列表--门店权限
     */
    public PagingResult<TerminalMemberVolumeDTO> getTerminalCountListForStore(MemberVolumeCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        Assert.notNull(condition.getRegisterStoreId(), "门店id不能为空");
        condition.setEndTime(DateUtils.addDate(condition.getEndTime()));
        RowBounds rowBounds = new RowBounds(condition.offset(), condition.limit());
        List<TerminalMemberVolume> list = memberCountDalMapper.getTerminalCountListWithRowBounds(condition, rowBounds);
        logger.info("按照终端类型统计某个时间段会员量--门店权限:" + list);
        PageInfo<TerminalMemberVolume> pageInfo = new PageInfo<>(list);

        List<TerminalMemberVolumeDTO> terminalMemberVolumeDTOList = CJBeanUtils.convertCollection(
                list, TerminalMemberVolumeDTO.class, (source, target) -> {
                    if (source.getRegisterTerminalType() != null) {
                        target.setTerminalTypeText(source.getRegisterTerminalType() == null ? "-" : MbrSourceTerminal.getSourceTerminal(source.getRegisterTerminalType()).name);//杨括修改
                    }
                });
        return new PagingResult<>(pageInfo.getPageSize(), pageInfo.getPageNum(),
                pageInfo.getTotal(), terminalMemberVolumeDTOList);
    }

    private TerminalMemberVolumeAndTotalDTO terminalCountListConvert(MemberVolumeCondition condition,
                                                                     List<TerminalMemberVolume> list) {
        List<TerminalMemberVolumeDTO> terminalMemberVolumeDTOList = new ArrayList<>();
        int totalCount = memberCountDalMapper.getTotalCount(condition.getMerchantId());//总数量
        int timeCount = memberCountDalMapper.getTimeCount(condition);////某段时间总数量
        TotalDTO totalDTO = new TotalDTO();
        totalDTO.setTimeCount(timeCount);
        totalDTO.setTotalCount(totalCount);

        list.forEach(terminalMemberVolume -> {
            TerminalMemberVolumeDTO terminalMemberVolumeDTO = new TerminalMemberVolumeDTO();
            BeanUtils.copyProperties(terminalMemberVolume, terminalMemberVolumeDTO);
            //设置终端类型名字
            terminalMemberVolumeDTO.setTerminalTypeText(terminalMemberVolume.getRegisterTerminalType() == null ? "-" : MbrSourceTerminal.getSourceTerminal(
                    terminalMemberVolume.getRegisterTerminalType()).name);
            terminalMemberVolumeDTOList.add(terminalMemberVolumeDTO);
        });
        TerminalMemberVolumeAndTotalDTO dataTotal = new TerminalMemberVolumeAndTotalDTO();
        dataTotal.setDatas(terminalMemberVolumeDTOList);
        dataTotal.setTotal(totalDTO);
        return dataTotal;
    }

    /**
     * 会员量详情列表
     */
    private PagingResult<MemberVolumeDetailDTO> getMemberVolumeDetail(MemberVolumeDetailCondition condition) {
        logger.info("会员量详情列表参数值:" + condition);
        RowBounds rowBounds = new RowBounds(condition.offset(), condition.limit());
        if (condition.getRegisterStoreId() != null) {
            condition.setMerchantUserId(null);
        }
        List<MemberVolumeDetail> list = memberCountDalMapper.queryMemberVolumeListWithRowBounds(condition, rowBounds);
        logger.info("会员量详情列表:" + list);
        PageInfo<MemberVolumeDetail> pageInfo = new PageInfo<>(list);
        List<MemberVolumeDetailDTO> memberVolumeDetailDTOList = CJBeanUtils.convertCollection(
                list, MemberVolumeDetailDTO.class, (source, target) -> {
                    //性别
                    if (source.getSex() != null) {
                        target.setSexText(Sex.getSex(source.getSex()).name);
                    }
                    //终端类型
                    if (source.getTerminalType() != null) {
                        target.setTerminalTypeText(MbrSourceTerminal.getSourceTerminal(source.getTerminalType()).name);//杨括修改
                    }

                    if (source.getStoreUser() == null) {
                        target.setStoreUser("-");
                    }

                    if (source.getMobile() == null) {
                        target.setMobile("-");
                    }
                    if (source.getName() == null) {
                        target.setName("-");
                    }
                    if (source.getTerminalType() == null) {
                        target.setTerminalTypeText("-");
                    }
                });

        return new PagingResult<>(pageInfo.getPageSize(), pageInfo.getPageNum(),
                pageInfo.getTotal(), memberVolumeDetailDTOList);
    }


    /**
     * 会员量--商户权限
     */
    public PagingResult<MemberVolumeDetailDTO> getMemberVolumeDetailForMerchant(
            MemberVolumeDetailCondition condition) {
        logger.debug("会员量--商户权限参数值:" + condition);
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        condition.setEndTime(DateUtils.addDate(condition.getEndTime()));
        return getMemberVolumeDetail(condition);
    }

    /**
     * 会员量---门店权限
     */
    public PagingResult<MemberVolumeDetailDTO> getMemberVolumeDetailForStore(
            MemberVolumeDetailCondition condition) {
        logger.debug("会员量--门店权限参数值:" + condition);
        condition.setEndTime(DateUtils.addDate(condition.getEndTime()));
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        Assert.notNull(condition.getRegisterStoreId(), "门店id不能为空");
        return getMemberVolumeDetail(condition);
    }
}
